home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / cookielib.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  40KB  |  1,445 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __all__ = [
  5.     'Cookie',
  6.     'CookieJar',
  7.     'CookiePolicy',
  8.     'DefaultCookiePolicy',
  9.     'FileCookieJar',
  10.     'LWPCookieJar',
  11.     'LoadError',
  12.     'MozillaCookieJar']
  13. import re
  14. import urlparse
  15. import copy
  16. import time
  17. import urllib
  18.  
  19. try:
  20.     import threading as _threading
  21. except ImportError:
  22.     import dummy_threading as _threading
  23.  
  24. import httplib
  25. from calendar import timegm
  26. debug = False
  27. logger = None
  28.  
  29. def _debug(*args):
  30.     global logger
  31.     if not debug:
  32.         return None
  33.     
  34.     if not logger:
  35.         import logging as logging
  36.         logger = logging.getLogger('cookielib')
  37.     
  38.     return logger.debug(*args)
  39.  
  40. DEFAULT_HTTP_PORT = str(httplib.HTTP_PORT)
  41. MISSING_FILENAME_TEXT = 'a filename was not supplied (nor was the CookieJar instance initialised with one)'
  42.  
  43. def _warn_unhandled_exception():
  44.     import warnings as warnings
  45.     import traceback as traceback
  46.     import StringIO as StringIO
  47.     f = StringIO.StringIO()
  48.     traceback.print_exc(None, f)
  49.     msg = f.getvalue()
  50.     warnings.warn('cookielib bug!\n%s' % msg, stacklevel = 2)
  51.  
  52. EPOCH_YEAR = 1970
  53.  
  54. def _timegm(tt):
  55.     (year, month, mday, hour, min, sec) = tt[:6]
  56.     if year >= EPOCH_YEAR:
  57.         pass
  58.  
  59. DAYS = [
  60.     'Mon',
  61.     'Tue',
  62.     'Wed',
  63.     'Thu',
  64.     'Fri',
  65.     'Sat',
  66.     'Sun']
  67. MONTHS = [
  68.     'Jan',
  69.     'Feb',
  70.     'Mar',
  71.     'Apr',
  72.     'May',
  73.     'Jun',
  74.     'Jul',
  75.     'Aug',
  76.     'Sep',
  77.     'Oct',
  78.     'Nov',
  79.     'Dec']
  80. MONTHS_LOWER = []
  81. for month in MONTHS:
  82.     MONTHS_LOWER.append(month.lower())
  83.  
  84.  
  85. def time2isoz(t = None):
  86.     if t is None:
  87.         t = time.time()
  88.     
  89.     (year, mon, mday, hour, min, sec) = time.gmtime(t)[:6]
  90.     return '%04d-%02d-%02d %02d:%02d:%02dZ' % (year, mon, mday, hour, min, sec)
  91.  
  92.  
  93. def time2netscape(t = None):
  94.     if t is None:
  95.         t = time.time()
  96.     
  97.     (year, mon, mday, hour, min, sec, wday) = time.gmtime(t)[:7]
  98.     return '%s %02d-%s-%04d %02d:%02d:%02d GMT' % (DAYS[wday], mday, MONTHS[mon - 1], year, hour, min, sec)
  99.  
  100. UTC_ZONES = {
  101.     'GMT': None,
  102.     'UTC': None,
  103.     'UT': None,
  104.     'Z': None }
  105. TIMEZONE_RE = re.compile('^([-+])?(\\d\\d?):?(\\d\\d)?$')
  106.  
  107. def offset_from_tz_string(tz):
  108.     offset = None
  109.     if tz in UTC_ZONES:
  110.         offset = 0
  111.     else:
  112.         m = TIMEZONE_RE.search(tz)
  113.         if m:
  114.             offset = 3600 * int(m.group(2))
  115.             if m.group(3):
  116.                 offset = offset + 60 * int(m.group(3))
  117.             
  118.             if m.group(1) == '-':
  119.                 offset = -offset
  120.             
  121.         
  122.     return offset
  123.  
  124.  
  125. def _str2time(day, mon, yr, hr, min, sec, tz):
  126.     
  127.     try:
  128.         mon = MONTHS_LOWER.index(mon.lower()) + 1
  129.     except ValueError:
  130.         
  131.         try:
  132.             imon = int(mon)
  133.         except ValueError:
  134.             return None
  135.  
  136.         if imon <= imon:
  137.             pass
  138.         elif imon <= 12:
  139.             mon = imon
  140.         else:
  141.             return None
  142.     except:
  143.         1
  144.  
  145.     if hr is None:
  146.         hr = 0
  147.     
  148.     if min is None:
  149.         min = 0
  150.     
  151.     if sec is None:
  152.         sec = 0
  153.     
  154.     yr = int(yr)
  155.     day = int(day)
  156.     hr = int(hr)
  157.     min = int(min)
  158.     sec = int(sec)
  159.     if yr < 1000:
  160.         cur_yr = time.localtime(time.time())[0]
  161.         m = cur_yr % 100
  162.         tmp = yr
  163.         yr = yr + cur_yr - m
  164.         m = m - tmp
  165.         if abs(m) > 50:
  166.             if m > 0:
  167.                 yr = yr + 100
  168.             else:
  169.                 yr = yr - 100
  170.         
  171.     
  172.     t = _timegm((yr, mon, day, hr, min, sec, tz))
  173.     if t is not None:
  174.         if tz is None:
  175.             tz = 'UTC'
  176.         
  177.         tz = tz.upper()
  178.         offset = offset_from_tz_string(tz)
  179.         if offset is None:
  180.             return None
  181.         
  182.         t = t - offset
  183.     
  184.     return t
  185.  
  186. STRICT_DATE_RE = re.compile('^[SMTWF][a-z][a-z], (\\d\\d) ([JFMASOND][a-z][a-z]) (\\d\\d\\d\\d) (\\d\\d):(\\d\\d):(\\d\\d) GMT$')
  187. WEEKDAY_RE = re.compile('^(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)[a-z]*,?\\s*', re.I)
  188. LOOSE_HTTP_DATE_RE = re.compile('^\n    (\\d\\d?)            # day\n       (?:\\s+|[-\\/])\n    (\\w+)              # month\n        (?:\\s+|[-\\/])\n    (\\d+)              # year\n    (?:\n          (?:\\s+|:)    # separator before clock\n       (\\d\\d?):(\\d\\d)  # hour:min\n       (?::(\\d\\d))?    # optional seconds\n    )?                 # optional clock\n       \\s*\n    ([-+]?\\d{2,4}|(?![APap][Mm]\\b)[A-Za-z]+)? # timezone\n       \\s*\n    (?:\\(\\w+\\))?       # ASCII representation of timezone in parens.\n       \\s*$', re.X)
  189.  
  190. def http2time(text):
  191.     m = STRICT_DATE_RE.search(text)
  192.     if m:
  193.         g = m.groups()
  194.         mon = MONTHS_LOWER.index(g[1].lower()) + 1
  195.         tt = (int(g[2]), mon, int(g[0]), int(g[3]), int(g[4]), float(g[5]))
  196.         return _timegm(tt)
  197.     
  198.     text = text.lstrip()
  199.     text = WEEKDAY_RE.sub('', text, 1)
  200.     (day, mon, yr, hr, min, sec, tz) = [
  201.         None] * 7
  202.     m = LOOSE_HTTP_DATE_RE.search(text)
  203.     if m is not None:
  204.         (day, mon, yr, hr, min, sec, tz) = m.groups()
  205.     else:
  206.         return None
  207.     return _str2time(day, mon, yr, hr, min, sec, tz)
  208.  
  209. ISO_DATE_RE = re.compile('^\n    (\\d{4})              # year\n       [-\\/]?\n    (\\d\\d?)              # numerical month\n       [-\\/]?\n    (\\d\\d?)              # day\n   (?:\n         (?:\\s+|[-:Tt])  # separator before clock\n      (\\d\\d?):?(\\d\\d)    # hour:min\n      (?::?(\\d\\d(?:\\.\\d*)?))?  # optional seconds (and fractional)\n   )?                    # optional clock\n      \\s*\n   ([-+]?\\d\\d?:?(:?\\d\\d)?\n    |Z|z)?               # timezone  (Z is "zero meridian", i.e. GMT)\n      \\s*$', re.X)
  210.  
  211. def iso2time(text):
  212.     text = text.lstrip()
  213.     (day, mon, yr, hr, min, sec, tz) = [
  214.         None] * 7
  215.     m = ISO_DATE_RE.search(text)
  216.     if m is not None:
  217.         (yr, mon, day, hr, min, sec, tz, _) = m.groups()
  218.     else:
  219.         return None
  220.     return _str2time(day, mon, yr, hr, min, sec, tz)
  221.  
  222.  
  223. def unmatched(match):
  224.     (start, end) = match.span(0)
  225.     return match.string[:start] + match.string[end:]
  226.  
  227. HEADER_TOKEN_RE = re.compile('^\\s*([^=\\s;,]+)')
  228. HEADER_QUOTED_VALUE_RE = re.compile('^\\s*=\\s*\\"([^\\"\\\\]*(?:\\\\.[^\\"\\\\]*)*)\\"')
  229. HEADER_VALUE_RE = re.compile('^\\s*=\\s*([^\\s;,]*)')
  230. HEADER_ESCAPE_RE = re.compile('\\\\(.)')
  231.  
  232. def split_header_words(header_values):
  233.     result = []
  234.     for text in header_values:
  235.         orig_text = text
  236.         pairs = []
  237.         while text:
  238.             m = HEADER_TOKEN_RE.search(text)
  239.             if m:
  240.                 text = unmatched(m)
  241.                 name = m.group(1)
  242.                 m = HEADER_QUOTED_VALUE_RE.search(text)
  243.                 if m:
  244.                     text = unmatched(m)
  245.                     value = m.group(1)
  246.                     value = HEADER_ESCAPE_RE.sub('\\1', value)
  247.                 else:
  248.                     m = HEADER_VALUE_RE.search(text)
  249.                     if m:
  250.                         text = unmatched(m)
  251.                         value = m.group(1)
  252.                         value = value.rstrip()
  253.                     else:
  254.                         value = None
  255.                 pairs.append((name, value))
  256.                 continue
  257.             if text.lstrip().startswith(','):
  258.                 text = text.lstrip()[1:]
  259.                 if pairs:
  260.                     result.append(pairs)
  261.                 
  262.                 pairs = []
  263.                 continue
  264.             (non_junk, nr_junk_chars) = re.subn('^[=\\s;]*', '', text)
  265.             text = non_junk
  266.         if pairs:
  267.             result.append(pairs)
  268.             continue
  269.     
  270.     return result
  271.  
  272. HEADER_JOIN_ESCAPE_RE = re.compile('([\\"\\\\])')
  273.  
  274. def join_header_words(lists):
  275.     headers = []
  276.     for pairs in lists:
  277.         attr = []
  278.         for k, v in pairs:
  279.             if v is not None:
  280.                 if not re.search('^\\w+$', v):
  281.                     v = HEADER_JOIN_ESCAPE_RE.sub('\\\\\\1', v)
  282.                     v = '"%s"' % v
  283.                 
  284.                 k = '%s=%s' % (k, v)
  285.             
  286.             attr.append(k)
  287.         
  288.         if attr:
  289.             headers.append('; '.join(attr))
  290.             continue
  291.     
  292.     return ', '.join(headers)
  293.  
  294.  
  295. def parse_ns_headers(ns_headers):
  296.     known_attrs = ('expires', 'domain', 'path', 'secure', 'port', 'max-age')
  297.     result = []
  298.     for ns_header in ns_headers:
  299.         pairs = []
  300.         version_set = False
  301.         for ii, param in enumerate(re.split(';\\s*', ns_header)):
  302.             param = param.rstrip()
  303.             if param == '':
  304.                 continue
  305.             
  306.             if '=' not in param:
  307.                 k = param
  308.                 v = None
  309.             else:
  310.                 (k, v) = re.split('\\s*=\\s*', param, 1)
  311.                 k = k.lstrip()
  312.             if ii != 0:
  313.                 lc = k.lower()
  314.                 if lc in known_attrs:
  315.                     k = lc
  316.                 
  317.                 if k == 'version':
  318.                     version_set = True
  319.                 
  320.                 if k == 'expires':
  321.                     if v.startswith('"'):
  322.                         v = v[1:]
  323.                     
  324.                     if v.endswith('"'):
  325.                         v = v[:-1]
  326.                     
  327.                     v = http2time(v)
  328.                 
  329.             
  330.             pairs.append((k, v))
  331.         
  332.         if pairs:
  333.             if not version_set:
  334.                 pairs.append(('version', '0'))
  335.             
  336.             result.append(pairs)
  337.             continue
  338.     
  339.     return result
  340.  
  341. IPV4_RE = re.compile('\\.\\d+$')
  342.  
  343. def is_HDN(text):
  344.     if IPV4_RE.search(text):
  345.         return False
  346.     
  347.     if text == '':
  348.         return False
  349.     
  350.     if text[0] == '.' or text[-1] == '.':
  351.         return False
  352.     
  353.     return True
  354.  
  355.  
  356. def domain_match(A, B):
  357.     A = A.lower()
  358.     B = B.lower()
  359.     if A == B:
  360.         return True
  361.     
  362.     if not is_HDN(A):
  363.         return False
  364.     
  365.     i = A.rfind(B)
  366.     if i == -1 or i == 0:
  367.         return False
  368.     
  369.     if not B.startswith('.'):
  370.         return False
  371.     
  372.     if not is_HDN(B[1:]):
  373.         return False
  374.     
  375.     return True
  376.  
  377.  
  378. def liberal_is_HDN(text):
  379.     if IPV4_RE.search(text):
  380.         return False
  381.     
  382.     return True
  383.  
  384.  
  385. def user_domain_match(A, B):
  386.     A = A.lower()
  387.     B = B.lower()
  388.     if not liberal_is_HDN(A) and liberal_is_HDN(B):
  389.         if A == B:
  390.             return True
  391.         
  392.         return False
  393.     
  394.     initial_dot = B.startswith('.')
  395.     if initial_dot and A.endswith(B):
  396.         return True
  397.     
  398.     if not initial_dot and A == B:
  399.         return True
  400.     
  401.     return False
  402.  
  403. cut_port_re = re.compile(':\\d+$')
  404.  
  405. def request_host(request):
  406.     url = request.get_full_url()
  407.     host = urlparse.urlparse(url)[1]
  408.     if host == '':
  409.         host = request.get_header('Host', '')
  410.     
  411.     host = cut_port_re.sub('', host, 1)
  412.     return host.lower()
  413.  
  414.  
  415. def eff_request_host(request):
  416.     erhn = req_host = request_host(request)
  417.     if req_host.find('.') == -1 and not IPV4_RE.search(req_host):
  418.         erhn = req_host + '.local'
  419.     
  420.     return (req_host, erhn)
  421.  
  422.  
  423. def request_path(request):
  424.     url = request.get_full_url()
  425.     (path, parameters, query, frag) = urlparse.urlparse(url)[2:]
  426.     if parameters:
  427.         path = '%s;%s' % (path, parameters)
  428.     
  429.     path = escape_path(path)
  430.     req_path = urlparse.urlunparse(('', '', path, '', query, frag))
  431.     if not req_path.startswith('/'):
  432.         req_path = '/' + req_path
  433.     
  434.     return req_path
  435.  
  436.  
  437. def request_port(request):
  438.     host = request.get_host()
  439.     i = host.find(':')
  440.     if i >= 0:
  441.         port = host[i + 1:]
  442.         
  443.         try:
  444.             int(port)
  445.         except ValueError:
  446.             _debug("nonnumeric port: '%s'", port)
  447.             return None
  448.         except:
  449.             None<EXCEPTION MATCH>ValueError
  450.         
  451.  
  452.     None<EXCEPTION MATCH>ValueError
  453.     port = DEFAULT_HTTP_PORT
  454.     return port
  455.  
  456. HTTP_PATH_SAFE = "%/;:@&=+$,!~*'()"
  457. ESCAPED_CHAR_RE = re.compile('%([0-9a-fA-F][0-9a-fA-F])')
  458.  
  459. def uppercase_escaped_char(match):
  460.     return '%%%s' % match.group(1).upper()
  461.  
  462.  
  463. def escape_path(path):
  464.     if isinstance(path, unicode):
  465.         path = path.encode('utf-8')
  466.     
  467.     path = urllib.quote(path, HTTP_PATH_SAFE)
  468.     path = ESCAPED_CHAR_RE.sub(uppercase_escaped_char, path)
  469.     return path
  470.  
  471.  
  472. def reach(h):
  473.     i = h.find('.')
  474.     if i >= 0:
  475.         b = h[i + 1:]
  476.         i = b.find('.')
  477.         if is_HDN(h):
  478.             pass
  479.         None if i >= 0 or b == 'local' else b == 'local'
  480.     
  481.     return h
  482.  
  483.  
  484. def is_third_party(request):
  485.     req_host = request_host(request)
  486.     if not domain_match(req_host, reach(request.get_origin_req_host())):
  487.         return True
  488.     else:
  489.         return False
  490.  
  491.  
  492. class Cookie:
  493.     
  494.     def __init__(self, version, name, value, port, port_specified, domain, domain_specified, domain_initial_dot, path, path_specified, secure, expires, discard, comment, comment_url, rest, rfc2109 = False):
  495.         if version is not None:
  496.             version = int(version)
  497.         
  498.         if expires is not None:
  499.             expires = int(expires)
  500.         
  501.         if port is None and port_specified is True:
  502.             raise ValueError('if port is None, port_specified must be false')
  503.         
  504.         self.version = version
  505.         self.name = name
  506.         self.value = value
  507.         self.port = port
  508.         self.port_specified = port_specified
  509.         self.domain = domain.lower()
  510.         self.domain_specified = domain_specified
  511.         self.domain_initial_dot = domain_initial_dot
  512.         self.path = path
  513.         self.path_specified = path_specified
  514.         self.secure = secure
  515.         self.expires = expires
  516.         self.discard = discard
  517.         self.comment = comment
  518.         self.comment_url = comment_url
  519.         self.rfc2109 = rfc2109
  520.         self._rest = copy.copy(rest)
  521.  
  522.     
  523.     def has_nonstandard_attr(self, name):
  524.         return name in self._rest
  525.  
  526.     
  527.     def get_nonstandard_attr(self, name, default = None):
  528.         return self._rest.get(name, default)
  529.  
  530.     
  531.     def set_nonstandard_attr(self, name, value):
  532.         self._rest[name] = value
  533.  
  534.     
  535.     def is_expired(self, now = None):
  536.         if now is None:
  537.             now = time.time()
  538.         
  539.         if self.expires is not None and self.expires <= now:
  540.             return True
  541.         
  542.         return False
  543.  
  544.     
  545.     def __str__(self):
  546.         if self.port is None:
  547.             p = ''
  548.         else:
  549.             p = ':' + self.port
  550.         limit = self.domain + p + self.path
  551.         if self.value is not None:
  552.             namevalue = '%s=%s' % (self.name, self.value)
  553.         else:
  554.             namevalue = self.name
  555.         return '<Cookie %s for %s>' % (namevalue, limit)
  556.  
  557.     
  558.     def __repr__(self):
  559.         args = []
  560.         for name in ('version', 'name', 'value', 'port', 'port_specified', 'domain', 'domain_specified', 'domain_initial_dot', 'path', 'path_specified', 'secure', 'expires', 'discard', 'comment', 'comment_url'):
  561.             attr = getattr(self, name)
  562.             args.append('%s=%s' % (name, repr(attr)))
  563.         
  564.         args.append('rest=%s' % repr(self._rest))
  565.         args.append('rfc2109=%s' % repr(self.rfc2109))
  566.         return 'Cookie(%s)' % ', '.join(args)
  567.  
  568.  
  569.  
  570. class CookiePolicy:
  571.     
  572.     def set_ok(self, cookie, request):
  573.         raise NotImplementedError()
  574.  
  575.     
  576.     def return_ok(self, cookie, request):
  577.         raise NotImplementedError()
  578.  
  579.     
  580.     def domain_return_ok(self, domain, request):
  581.         return True
  582.  
  583.     
  584.     def path_return_ok(self, path, request):
  585.         return True
  586.  
  587.  
  588.  
  589. class DefaultCookiePolicy(CookiePolicy):
  590.     DomainStrictNoDots = 1
  591.     DomainStrictNonDomain = 2
  592.     DomainRFC2965Match = 4
  593.     DomainLiberal = 0
  594.     DomainStrict = DomainStrictNoDots | DomainStrictNonDomain
  595.     
  596.     def __init__(self, blocked_domains = None, allowed_domains = None, netscape = True, rfc2965 = False, rfc2109_as_netscape = None, hide_cookie2 = False, strict_domain = False, strict_rfc2965_unverifiable = True, strict_ns_unverifiable = False, strict_ns_domain = DomainLiberal, strict_ns_set_initial_dollar = False, strict_ns_set_path = False):
  597.         self.netscape = netscape
  598.         self.rfc2965 = rfc2965
  599.         self.rfc2109_as_netscape = rfc2109_as_netscape
  600.         self.hide_cookie2 = hide_cookie2
  601.         self.strict_domain = strict_domain
  602.         self.strict_rfc2965_unverifiable = strict_rfc2965_unverifiable
  603.         self.strict_ns_unverifiable = strict_ns_unverifiable
  604.         self.strict_ns_domain = strict_ns_domain
  605.         self.strict_ns_set_initial_dollar = strict_ns_set_initial_dollar
  606.         self.strict_ns_set_path = strict_ns_set_path
  607.         if blocked_domains is not None:
  608.             self._blocked_domains = tuple(blocked_domains)
  609.         else:
  610.             self._blocked_domains = ()
  611.         if allowed_domains is not None:
  612.             allowed_domains = tuple(allowed_domains)
  613.         
  614.         self._allowed_domains = allowed_domains
  615.  
  616.     
  617.     def blocked_domains(self):
  618.         return self._blocked_domains
  619.  
  620.     
  621.     def set_blocked_domains(self, blocked_domains):
  622.         self._blocked_domains = tuple(blocked_domains)
  623.  
  624.     
  625.     def is_blocked(self, domain):
  626.         for blocked_domain in self._blocked_domains:
  627.             if user_domain_match(domain, blocked_domain):
  628.                 return True
  629.                 continue
  630.         
  631.         return False
  632.  
  633.     
  634.     def allowed_domains(self):
  635.         return self._allowed_domains
  636.  
  637.     
  638.     def set_allowed_domains(self, allowed_domains):
  639.         if allowed_domains is not None:
  640.             allowed_domains = tuple(allowed_domains)
  641.         
  642.         self._allowed_domains = allowed_domains
  643.  
  644.     
  645.     def is_not_allowed(self, domain):
  646.         if self._allowed_domains is None:
  647.             return False
  648.         
  649.         for allowed_domain in self._allowed_domains:
  650.             if user_domain_match(domain, allowed_domain):
  651.                 return False
  652.                 continue
  653.         
  654.         return True
  655.  
  656.     
  657.     def set_ok(self, cookie, request):
  658.         _debug(' - checking cookie %s=%s', cookie.name, cookie.value)
  659.         for n in ('version', 'verifiability', 'name', 'path', 'domain', 'port'):
  660.             fn_name = 'set_ok_' + n
  661.             fn = getattr(self, fn_name)
  662.             if not fn(cookie, request):
  663.                 return False
  664.                 continue
  665.         
  666.         return True
  667.  
  668.     
  669.     def set_ok_version(self, cookie, request):
  670.         if cookie.version is None:
  671.             _debug('   Set-Cookie2 without version attribute (%s=%s)', cookie.name, cookie.value)
  672.             return False
  673.         
  674.         if cookie.version > 0 and not (self.rfc2965):
  675.             _debug('   RFC 2965 cookies are switched off')
  676.             return False
  677.         elif cookie.version == 0 and not (self.netscape):
  678.             _debug('   Netscape cookies are switched off')
  679.             return False
  680.         
  681.         return True
  682.  
  683.     
  684.     def set_ok_verifiability(self, cookie, request):
  685.         if request.is_unverifiable() and is_third_party(request):
  686.             if cookie.version > 0 and self.strict_rfc2965_unverifiable:
  687.                 _debug('   third-party RFC 2965 cookie during unverifiable transaction')
  688.                 return False
  689.             elif cookie.version == 0 and self.strict_ns_unverifiable:
  690.                 _debug('   third-party Netscape cookie during unverifiable transaction')
  691.                 return False
  692.             
  693.         
  694.         return True
  695.  
  696.     
  697.     def set_ok_name(self, cookie, request):
  698.         if cookie.version == 0 and self.strict_ns_set_initial_dollar and cookie.name.startswith('$'):
  699.             _debug("   illegal name (starts with '$'): '%s'", cookie.name)
  700.             return False
  701.         
  702.         return True
  703.  
  704.     
  705.     def set_ok_path(self, cookie, request):
  706.         if cookie.path_specified:
  707.             req_path = request_path(request)
  708.             if (cookie.version > 0 or cookie.version == 0 or self.strict_ns_set_path) and not req_path.startswith(cookie.path):
  709.                 _debug('   path attribute %s is not a prefix of request path %s', cookie.path, req_path)
  710.                 return False
  711.             
  712.         
  713.         return True
  714.  
  715.     
  716.     def set_ok_domain(self, cookie, request):
  717.         if self.is_blocked(cookie.domain):
  718.             _debug('   domain %s is in user block-list', cookie.domain)
  719.             return False
  720.         
  721.         if self.is_not_allowed(cookie.domain):
  722.             _debug('   domain %s is not in user allow-list', cookie.domain)
  723.             return False
  724.         
  725.         if cookie.domain_specified:
  726.             (req_host, erhn) = eff_request_host(request)
  727.             domain = cookie.domain
  728.             if self.strict_domain and domain.count('.') >= 2:
  729.                 i = domain.rfind('.')
  730.                 j = domain.rfind('.', 0, i)
  731.                 if j == 0:
  732.                     tld = domain[i + 1:]
  733.                     sld = domain[j + 1:i]
  734.                     if sld.lower() in ('co', 'ac', 'com', 'edu', 'org', 'net', 'gov', 'mil', 'int', 'aero', 'biz', 'cat', 'coop', 'info', 'jobs', 'mobi', 'museum', 'name', 'pro', 'travel', 'eu') and len(tld) == 2:
  735.                         _debug('   country-code second level domain %s', domain)
  736.                         return False
  737.                     
  738.                 
  739.             
  740.             if domain.startswith('.'):
  741.                 undotted_domain = domain[1:]
  742.             else:
  743.                 undotted_domain = domain
  744.             embedded_dots = undotted_domain.find('.') >= 0
  745.             if not embedded_dots and domain != '.local':
  746.                 _debug('   non-local domain %s contains no embedded dot', domain)
  747.                 return False
  748.             
  749.             if cookie.version == 0:
  750.                 if not erhn.endswith(domain) and not erhn.startswith('.') and not ('.' + erhn).endswith(domain):
  751.                     _debug('   effective request-host %s (even with added initial dot) does not end end with %s', erhn, domain)
  752.                     return False
  753.                 
  754.             
  755.             if cookie.version > 0 or self.strict_ns_domain & self.DomainRFC2965Match:
  756.                 if not domain_match(erhn, domain):
  757.                     _debug('   effective request-host %s does not domain-match %s', erhn, domain)
  758.                     return False
  759.                 
  760.             
  761.             if cookie.version > 0 or self.strict_ns_domain & self.DomainStrictNoDots:
  762.                 host_prefix = req_host[:-len(domain)]
  763.                 if host_prefix.find('.') >= 0 and not IPV4_RE.search(req_host):
  764.                     _debug('   host prefix %s for domain %s contains a dot', host_prefix, domain)
  765.                     return False
  766.                 
  767.             
  768.         
  769.         return True
  770.  
  771.     
  772.     def set_ok_port(self, cookie, request):
  773.         if cookie.port_specified:
  774.             req_port = request_port(request)
  775.             if req_port is None:
  776.                 req_port = '80'
  777.             else:
  778.                 req_port = str(req_port)
  779.             for p in cookie.port.split(','):
  780.                 
  781.                 try:
  782.                     int(p)
  783.                 except ValueError:
  784.                     _debug('   bad port %s (not numeric)', p)
  785.                     return False
  786.  
  787.                 if p == req_port:
  788.                     break
  789.                     continue
  790.             else:
  791.                 return False
  792.         
  793.         return True
  794.  
  795.     
  796.     def return_ok(self, cookie, request):
  797.         _debug(' - checking cookie %s=%s', cookie.name, cookie.value)
  798.         for n in ('version', 'verifiability', 'secure', 'expires', 'port', 'domain'):
  799.             fn_name = 'return_ok_' + n
  800.             fn = getattr(self, fn_name)
  801.             if not fn(cookie, request):
  802.                 return False
  803.                 continue
  804.         
  805.         return True
  806.  
  807.     
  808.     def return_ok_version(self, cookie, request):
  809.         if cookie.version > 0 and not (self.rfc2965):
  810.             _debug('   RFC 2965 cookies are switched off')
  811.             return False
  812.         elif cookie.version == 0 and not (self.netscape):
  813.             _debug('   Netscape cookies are switched off')
  814.             return False
  815.         
  816.         return True
  817.  
  818.     
  819.     def return_ok_verifiability(self, cookie, request):
  820.         if request.is_unverifiable() and is_third_party(request):
  821.             if cookie.version > 0 and self.strict_rfc2965_unverifiable:
  822.                 _debug('   third-party RFC 2965 cookie during unverifiable transaction')
  823.                 return False
  824.             elif cookie.version == 0 and self.strict_ns_unverifiable:
  825.                 _debug('   third-party Netscape cookie during unverifiable transaction')
  826.                 return False
  827.             
  828.         
  829.         return True
  830.  
  831.     
  832.     def return_ok_secure(self, cookie, request):
  833.         if cookie.secure and request.get_type() != 'https':
  834.             _debug('   secure cookie with non-secure request')
  835.             return False
  836.         
  837.         return True
  838.  
  839.     
  840.     def return_ok_expires(self, cookie, request):
  841.         if cookie.is_expired(self._now):
  842.             _debug('   cookie expired')
  843.             return False
  844.         
  845.         return True
  846.  
  847.     
  848.     def return_ok_port(self, cookie, request):
  849.         if cookie.port:
  850.             req_port = request_port(request)
  851.             if req_port is None:
  852.                 req_port = '80'
  853.             
  854.             for p in cookie.port.split(','):
  855.                 if p == req_port:
  856.                     break
  857.                     continue
  858.             else:
  859.                 return False
  860.         
  861.         return True
  862.  
  863.     
  864.     def return_ok_domain(self, cookie, request):
  865.         (req_host, erhn) = eff_request_host(request)
  866.         domain = cookie.domain
  867.         if cookie.version == 0 and self.strict_ns_domain & self.DomainStrictNonDomain and not (cookie.domain_specified) and domain != erhn:
  868.             _debug('   cookie with unspecified domain does not string-compare equal to request domain')
  869.             return False
  870.         
  871.         if cookie.version > 0 and not domain_match(erhn, domain):
  872.             _debug('   effective request-host name %s does not domain-match RFC 2965 cookie domain %s', erhn, domain)
  873.             return False
  874.         
  875.         if cookie.version == 0 and not ('.' + erhn).endswith(domain):
  876.             _debug('   request-host %s does not match Netscape cookie domain %s', req_host, domain)
  877.             return False
  878.         
  879.         return True
  880.  
  881.     
  882.     def domain_return_ok(self, domain, request):
  883.         (req_host, erhn) = eff_request_host(request)
  884.         if not req_host.startswith('.'):
  885.             req_host = '.' + req_host
  886.         
  887.         if not erhn.startswith('.'):
  888.             erhn = '.' + erhn
  889.         
  890.         if not req_host.endswith(domain) or erhn.endswith(domain):
  891.             return False
  892.         
  893.         if self.is_blocked(domain):
  894.             _debug('   domain %s is in user block-list', domain)
  895.             return False
  896.         
  897.         if self.is_not_allowed(domain):
  898.             _debug('   domain %s is not in user allow-list', domain)
  899.             return False
  900.         
  901.         return True
  902.  
  903.     
  904.     def path_return_ok(self, path, request):
  905.         _debug('- checking cookie path=%s', path)
  906.         req_path = request_path(request)
  907.         if not req_path.startswith(path):
  908.             _debug('  %s does not path-match %s', req_path, path)
  909.             return False
  910.         
  911.         return True
  912.  
  913.  
  914.  
  915. def vals_sorted_by_key(adict):
  916.     keys = adict.keys()
  917.     keys.sort()
  918.     return map(adict.get, keys)
  919.  
  920.  
  921. def deepvalues(mapping):
  922.     values = vals_sorted_by_key(mapping)
  923.     for obj in values:
  924.         mapping = False
  925.         
  926.         try:
  927.             obj.items
  928.         except AttributeError:
  929.             pass
  930.  
  931.         mapping = True
  932.         for subobj in deepvalues(obj):
  933.             yield subobj
  934.         
  935.         if not mapping:
  936.             yield obj
  937.             continue
  938.     
  939.  
  940.  
  941. class Absent:
  942.     pass
  943.  
  944.  
  945. class CookieJar:
  946.     non_word_re = re.compile('\\W')
  947.     quote_re = re.compile('([\\"\\\\])')
  948.     strict_domain_re = re.compile('\\.?[^.]*')
  949.     domain_re = re.compile('[^.]*')
  950.     dots_re = re.compile('^\\.+')
  951.     magic_re = '^\\#LWP-Cookies-(\\d+\\.\\d+)'
  952.     
  953.     def __init__(self, policy = None):
  954.         if policy is None:
  955.             policy = DefaultCookiePolicy()
  956.         
  957.         self._policy = policy
  958.         self._cookies_lock = _threading.RLock()
  959.         self._cookies = { }
  960.  
  961.     
  962.     def set_policy(self, policy):
  963.         self._policy = policy
  964.  
  965.     
  966.     def _cookies_for_domain(self, domain, request):
  967.         cookies = []
  968.         if not self._policy.domain_return_ok(domain, request):
  969.             return []
  970.         
  971.         _debug('Checking %s for cookies to return', domain)
  972.         cookies_by_path = self._cookies[domain]
  973.         for path in cookies_by_path.keys():
  974.             if not self._policy.path_return_ok(path, request):
  975.                 continue
  976.             
  977.             cookies_by_name = cookies_by_path[path]
  978.             for cookie in cookies_by_name.values():
  979.                 if not self._policy.return_ok(cookie, request):
  980.                     _debug('   not returning cookie')
  981.                     continue
  982.                 
  983.                 _debug("   it's a match")
  984.                 cookies.append(cookie)
  985.             
  986.         
  987.         return cookies
  988.  
  989.     
  990.     def _cookies_for_request(self, request):
  991.         cookies = []
  992.         for domain in self._cookies.keys():
  993.             cookies.extend(self._cookies_for_domain(domain, request))
  994.         
  995.         return cookies
  996.  
  997.     
  998.     def _cookie_attrs(self, cookies):
  999.         
  1000.         def decreasing_size(a, b):
  1001.             return cmp(len(b.path), len(a.path))
  1002.  
  1003.         cookies.sort(decreasing_size)
  1004.         version_set = False
  1005.         attrs = []
  1006.         for cookie in cookies:
  1007.             version = cookie.version
  1008.             if not version_set:
  1009.                 version_set = True
  1010.                 if version > 0:
  1011.                     attrs.append('$Version=%s' % version)
  1012.                 
  1013.             
  1014.             if cookie.value is not None and self.non_word_re.search(cookie.value) and version > 0:
  1015.                 value = self.quote_re.sub('\\\\\\1', cookie.value)
  1016.             else:
  1017.                 value = cookie.value
  1018.             if cookie.value is None:
  1019.                 attrs.append(cookie.name)
  1020.             else:
  1021.                 attrs.append('%s=%s' % (cookie.name, value))
  1022.             if version > 0:
  1023.                 if cookie.path_specified:
  1024.                     attrs.append('$Path="%s"' % cookie.path)
  1025.                 
  1026.                 if cookie.domain.startswith('.'):
  1027.                     domain = cookie.domain
  1028.                     if not (cookie.domain_initial_dot) and domain.startswith('.'):
  1029.                         domain = domain[1:]
  1030.                     
  1031.                     attrs.append('$Domain="%s"' % domain)
  1032.                 
  1033.                 if cookie.port is not None:
  1034.                     p = '$Port'
  1035.                     if cookie.port_specified:
  1036.                         p = p + '="%s"' % cookie.port
  1037.                     
  1038.                     attrs.append(p)
  1039.                 
  1040.             cookie.port is not None
  1041.         
  1042.         return attrs
  1043.  
  1044.     
  1045.     def add_cookie_header(self, request):
  1046.         _debug('add_cookie_header')
  1047.         self._cookies_lock.acquire()
  1048.         self._policy._now = self._now = int(time.time())
  1049.         cookies = self._cookies_for_request(request)
  1050.         attrs = self._cookie_attrs(cookies)
  1051.         if attrs:
  1052.             if not request.has_header('Cookie'):
  1053.                 request.add_unredirected_header('Cookie', '; '.join(attrs))
  1054.             
  1055.         
  1056.         if self._policy.rfc2965 and not (self._policy.hide_cookie2) and not request.has_header('Cookie2'):
  1057.             for cookie in cookies:
  1058.                 if cookie.version != 1:
  1059.                     request.add_unredirected_header('Cookie2', '$Version="1"')
  1060.                     break
  1061.                     continue
  1062.             
  1063.         
  1064.         self._cookies_lock.release()
  1065.         self.clear_expired_cookies()
  1066.  
  1067.     
  1068.     def _normalized_cookie_tuples(self, attrs_set):
  1069.         cookie_tuples = []
  1070.         boolean_attrs = ('discard', 'secure')
  1071.         value_attrs = ('version', 'expires', 'max-age', 'domain', 'path', 'port', 'comment', 'commenturl')
  1072.         for cookie_attrs in attrs_set:
  1073.             (name, value) = cookie_attrs[0]
  1074.             max_age_set = False
  1075.             bad_cookie = False
  1076.             standard = { }
  1077.             rest = { }
  1078.             for k, v in cookie_attrs[1:]:
  1079.                 lc = k.lower()
  1080.                 if lc in value_attrs or lc in boolean_attrs:
  1081.                     k = lc
  1082.                 
  1083.                 if k in boolean_attrs and v is None:
  1084.                     v = True
  1085.                 
  1086.                 if k in standard:
  1087.                     continue
  1088.                 
  1089.                 if k == 'domain':
  1090.                     if v is None:
  1091.                         _debug('   missing value for domain attribute')
  1092.                         bad_cookie = True
  1093.                         break
  1094.                     
  1095.                     v = v.lower()
  1096.                 
  1097.                 if k == 'expires':
  1098.                     if max_age_set:
  1099.                         continue
  1100.                     
  1101.                     if v is None:
  1102.                         _debug('   missing or invalid value for expires attribute: treating as session cookie')
  1103.                         continue
  1104.                     
  1105.                 
  1106.                 if k == 'max-age':
  1107.                     max_age_set = True
  1108.                     
  1109.                     try:
  1110.                         v = int(v)
  1111.                     except ValueError:
  1112.                         _debug('   missing or invalid (non-numeric) value for max-age attribute')
  1113.                         bad_cookie = True
  1114.                         break
  1115.  
  1116.                     k = 'expires'
  1117.                     v = self._now + v
  1118.                 
  1119.                 if k in value_attrs or k in boolean_attrs:
  1120.                     if v is None and k not in ('port', 'comment', 'commenturl'):
  1121.                         _debug('   missing value for %s attribute' % k)
  1122.                         bad_cookie = True
  1123.                         break
  1124.                     
  1125.                     standard[k] = v
  1126.                     continue
  1127.                 rest[k] = v
  1128.             
  1129.             if bad_cookie:
  1130.                 continue
  1131.             
  1132.             cookie_tuples.append((name, value, standard, rest))
  1133.         
  1134.         return cookie_tuples
  1135.  
  1136.     
  1137.     def _cookie_from_cookie_tuple(self, tup, request):
  1138.         (name, value, standard, rest) = tup
  1139.         domain = standard.get('domain', Absent)
  1140.         path = standard.get('path', Absent)
  1141.         port = standard.get('port', Absent)
  1142.         expires = standard.get('expires', Absent)
  1143.         version = standard.get('version', None)
  1144.         if version is not None:
  1145.             version = int(version)
  1146.         
  1147.         secure = standard.get('secure', False)
  1148.         discard = standard.get('discard', False)
  1149.         comment = standard.get('comment', None)
  1150.         comment_url = standard.get('commenturl', None)
  1151.         if path is not Absent and path != '':
  1152.             path_specified = True
  1153.             path = escape_path(path)
  1154.         else:
  1155.             path_specified = False
  1156.             path = request_path(request)
  1157.             i = path.rfind('/')
  1158.             if i != -1:
  1159.                 if version == 0:
  1160.                     path = path[:i]
  1161.                 else:
  1162.                     path = path[:i + 1]
  1163.             
  1164.             if len(path) == 0:
  1165.                 path = '/'
  1166.             
  1167.         domain_specified = domain is not Absent
  1168.         domain_initial_dot = False
  1169.         if domain_specified:
  1170.             domain_initial_dot = bool(domain.startswith('.'))
  1171.         
  1172.         if domain is Absent:
  1173.             (req_host, erhn) = eff_request_host(request)
  1174.             domain = erhn
  1175.         elif not domain.startswith('.'):
  1176.             domain = '.' + domain
  1177.         
  1178.         port_specified = False
  1179.         if port is not Absent:
  1180.             if port is None:
  1181.                 port = request_port(request)
  1182.             else:
  1183.                 port_specified = True
  1184.                 port = re.sub('\\s+', '', port)
  1185.         else:
  1186.             port = None
  1187.         if expires is Absent:
  1188.             expires = None
  1189.             discard = True
  1190.         elif expires <= self._now:
  1191.             
  1192.             try:
  1193.                 self.clear(domain, path, name)
  1194.             except KeyError:
  1195.                 pass
  1196.  
  1197.             _debug("Expiring cookie, domain='%s', path='%s', name='%s'", domain, path, name)
  1198.             return None
  1199.         
  1200.         return Cookie(version, name, value, port, port_specified, domain, domain_specified, domain_initial_dot, path, path_specified, secure, expires, discard, comment, comment_url, rest)
  1201.  
  1202.     
  1203.     def _cookies_from_attrs_set(self, attrs_set, request):
  1204.         cookie_tuples = self._normalized_cookie_tuples(attrs_set)
  1205.         cookies = []
  1206.         for tup in cookie_tuples:
  1207.             cookie = self._cookie_from_cookie_tuple(tup, request)
  1208.             if cookie:
  1209.                 cookies.append(cookie)
  1210.                 continue
  1211.         
  1212.         return cookies
  1213.  
  1214.     
  1215.     def _process_rfc2109_cookies(self, cookies):
  1216.         rfc2109_as_ns = getattr(self._policy, 'rfc2109_as_netscape', None)
  1217.         if rfc2109_as_ns is None:
  1218.             rfc2109_as_ns = not (self._policy.rfc2965)
  1219.         
  1220.         for cookie in cookies:
  1221.             if cookie.version == 1:
  1222.                 cookie.rfc2109 = True
  1223.                 if rfc2109_as_ns:
  1224.                     cookie.version = 0
  1225.                 
  1226.             rfc2109_as_ns
  1227.         
  1228.  
  1229.     
  1230.     def make_cookies(self, response, request):
  1231.         headers = response.info()
  1232.         rfc2965_hdrs = headers.getheaders('Set-Cookie2')
  1233.         ns_hdrs = headers.getheaders('Set-Cookie')
  1234.         rfc2965 = self._policy.rfc2965
  1235.         netscape = self._policy.netscape
  1236.         if not not rfc2965_hdrs or not ns_hdrs:
  1237.             if not not ns_hdrs or not rfc2965:
  1238.                 if (not rfc2965_hdrs or not netscape or not netscape) and not rfc2965:
  1239.                     return []
  1240.                 
  1241.         
  1242.         try:
  1243.             cookies = self._cookies_from_attrs_set(split_header_words(rfc2965_hdrs), request)
  1244.         except Exception:
  1245.             _warn_unhandled_exception()
  1246.             cookies = []
  1247.  
  1248.         if ns_hdrs and netscape:
  1249.             
  1250.             try:
  1251.                 ns_cookies = self._cookies_from_attrs_set(parse_ns_headers(ns_hdrs), request)
  1252.             except Exception:
  1253.                 _warn_unhandled_exception()
  1254.                 ns_cookies = []
  1255.  
  1256.             self._process_rfc2109_cookies(ns_cookies)
  1257.             if rfc2965:
  1258.                 lookup = { }
  1259.                 for cookie in cookies:
  1260.                     lookup[(cookie.domain, cookie.path, cookie.name)] = None
  1261.                 
  1262.                 
  1263.                 def no_matching_rfc2965(ns_cookie, lookup = lookup):
  1264.                     key = (ns_cookie.domain, ns_cookie.path, ns_cookie.name)
  1265.                     return key not in lookup
  1266.  
  1267.                 ns_cookies = filter(no_matching_rfc2965, ns_cookies)
  1268.             
  1269.             if ns_cookies:
  1270.                 cookies.extend(ns_cookies)
  1271.             
  1272.         
  1273.         return cookies
  1274.  
  1275.     
  1276.     def set_cookie_if_ok(self, cookie, request):
  1277.         self._cookies_lock.acquire()
  1278.         self._policy._now = self._now = int(time.time())
  1279.         if self._policy.set_ok(cookie, request):
  1280.             self.set_cookie(cookie)
  1281.         
  1282.         self._cookies_lock.release()
  1283.  
  1284.     
  1285.     def set_cookie(self, cookie):
  1286.         c = self._cookies
  1287.         self._cookies_lock.acquire()
  1288.         
  1289.         try:
  1290.             if cookie.domain not in c:
  1291.                 c[cookie.domain] = { }
  1292.             
  1293.             c2 = c[cookie.domain]
  1294.             if cookie.path not in c2:
  1295.                 c2[cookie.path] = { }
  1296.             
  1297.             c3 = c2[cookie.path]
  1298.             c3[cookie.name] = cookie
  1299.         finally:
  1300.             self._cookies_lock.release()
  1301.  
  1302.  
  1303.     
  1304.     def extract_cookies(self, response, request):
  1305.         _debug('extract_cookies: %s', response.info())
  1306.         self._cookies_lock.acquire()
  1307.         self._policy._now = self._now = int(time.time())
  1308.         for cookie in self.make_cookies(response, request):
  1309.             if self._policy.set_ok(cookie, request):
  1310.                 _debug(' setting cookie: %s', cookie)
  1311.                 self.set_cookie(cookie)
  1312.                 continue
  1313.         
  1314.         self._cookies_lock.release()
  1315.  
  1316.     
  1317.     def clear(self, domain = None, path = None, name = None):
  1318.         if name is not None:
  1319.             if domain is None or path is None:
  1320.                 raise ValueError('domain and path must be given to remove a cookie by name')
  1321.             
  1322.             del self._cookies[domain][path][name]
  1323.         elif path is not None:
  1324.             if domain is None:
  1325.                 raise ValueError('domain must be given to remove cookies by path')
  1326.             
  1327.             del self._cookies[domain][path]
  1328.         elif domain is not None:
  1329.             del self._cookies[domain]
  1330.         else:
  1331.             self._cookies = { }
  1332.  
  1333.     
  1334.     def clear_session_cookies(self):
  1335.         self._cookies_lock.acquire()
  1336.         for cookie in self:
  1337.             if cookie.discard:
  1338.                 self.clear(cookie.domain, cookie.path, cookie.name)
  1339.                 continue
  1340.         
  1341.         self._cookies_lock.release()
  1342.  
  1343.     
  1344.     def clear_expired_cookies(self):
  1345.         self._cookies_lock.acquire()
  1346.         now = time.time()
  1347.         for cookie in self:
  1348.             if cookie.is_expired(now):
  1349.                 self.clear(cookie.domain, cookie.path, cookie.name)
  1350.                 continue
  1351.         
  1352.         self._cookies_lock.release()
  1353.  
  1354.     
  1355.     def __iter__(self):
  1356.         return deepvalues(self._cookies)
  1357.  
  1358.     
  1359.     def __len__(self):
  1360.         i = 0
  1361.         for cookie in self:
  1362.             i = i + 1
  1363.         
  1364.         return i
  1365.  
  1366.     
  1367.     def __repr__(self):
  1368.         r = []
  1369.         for cookie in self:
  1370.             r.append(repr(cookie))
  1371.         
  1372.         return '<%s[%s]>' % (self.__class__, ', '.join(r))
  1373.  
  1374.     
  1375.     def __str__(self):
  1376.         r = []
  1377.         for cookie in self:
  1378.             r.append(str(cookie))
  1379.         
  1380.         return '<%s[%s]>' % (self.__class__, ', '.join(r))
  1381.  
  1382.  
  1383.  
  1384. class LoadError(IOError):
  1385.     pass
  1386.  
  1387.  
  1388. class FileCookieJar(CookieJar):
  1389.     
  1390.     def __init__(self, filename = None, delayload = False, policy = None):
  1391.         CookieJar.__init__(self, policy)
  1392.         if filename is not None:
  1393.             
  1394.             try:
  1395.                 filename + ''
  1396.             raise ValueError('filename must be string-like')
  1397.  
  1398.         
  1399.         self.filename = filename
  1400.         self.delayload = bool(delayload)
  1401.  
  1402.     
  1403.     def save(self, filename = None, ignore_discard = False, ignore_expires = False):
  1404.         raise NotImplementedError()
  1405.  
  1406.     
  1407.     def load(self, filename = None, ignore_discard = False, ignore_expires = False):
  1408.         if filename is None:
  1409.             if self.filename is not None:
  1410.                 filename = self.filename
  1411.             else:
  1412.                 raise ValueError(MISSING_FILENAME_TEXT)
  1413.         
  1414.         f = open(filename)
  1415.         
  1416.         try:
  1417.             self._really_load(f, filename, ignore_discard, ignore_expires)
  1418.         finally:
  1419.             f.close()
  1420.  
  1421.  
  1422.     
  1423.     def revert(self, filename = None, ignore_discard = False, ignore_expires = False):
  1424.         if filename is None:
  1425.             if self.filename is not None:
  1426.                 filename = self.filename
  1427.             else:
  1428.                 raise ValueError(MISSING_FILENAME_TEXT)
  1429.         
  1430.         self._cookies_lock.acquire()
  1431.         old_state = copy.deepcopy(self._cookies)
  1432.         self._cookies = { }
  1433.         
  1434.         try:
  1435.             self.load(filename, ignore_discard, ignore_expires)
  1436.         except (LoadError, IOError):
  1437.             self._cookies = old_state
  1438.             raise 
  1439.  
  1440.         self._cookies_lock.release()
  1441.  
  1442.  
  1443. from _LWPCookieJar import LWPCookieJar, lwp_cookie_str
  1444. from _MozillaCookieJar import MozillaCookieJar
  1445.